package com.xihuanjun.sdk.service;

import com.xihuanjun.sdk.dao.SapDeliveryNoteDao;
import com.xihuanjun.sdk.dao.SapReturnRequestDao;
import com.xihuanjun.sdk.entity.SapOrder;
import com.xihuanjun.sdk.entity.SapOrderItem;
import com.xihuanjun.sdk.entity.SapOrderItemBatch;
import com.xihuanjun.sdk.exception.QuantityNotSufficientException;
import com.xihuanjun.sdk.exception.SapException;
import com.xihuanjun.sdk.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * Copyright (C), 2024-08-29
 * FileName: ReturnRequestService
 * Author:   溪浣君
 * Date:     2024-08-29 11:49
 * Description: 退货请求相关业务
 */
@Service
@Slf4j
public class ReturnRequestService {

    @Autowired
    SapReturnRequestDao returnRequestDao;

    @Autowired
    SapDeliveryNoteDao deliveryNoteDao;

    /**
     * 把一个退货请求生成退货单的json，批次选择发货批次
     * @param orrrDocEntry 退货请求对象，现根据DocEntry获取退货请求，传过来
     * @param orderClass sapOrder的子类类型
     * @param batchNumberService 当获取不到发货批次时，获取批次列表的实现，在其中选一个批次作为收货批次
     * @return
     * @param <T>
     */
    public <T extends SapOrder> String getReturnJson(Long orrrDocEntry, Class<T> orderClass,IBatchNumberService batchNumberService) {
        log.debug("自动退货入库，请求：{}" + orrrDocEntry);
        T orrr = returnRequestDao.getObjectByPrimaryKey(orrrDocEntry.toString(), orderClass);
        SapOrderItem deliItem = (SapOrderItem) orrr.getDocumentLines().stream().filter(e -> ((SapOrderItem) e).getBaseEntry() != null).findFirst().orElse(null);
        SapOrder deliveryOrder=null;
        if(deliItem!=null){
            deliveryOrder = deliveryNoteDao.getObjectByPrimaryKey(deliItem.getBaseEntry().toString(),orderClass);
            log.debug("交货单号：{}",deliveryOrder.getDocEntry());
        }
        try {
            T reqReturn = orderClass.newInstance();
            reqReturn.setCardCode(orrr.getCardCode());
            reqReturn.setDocDate(orrr.getDocDate());
            reqReturn.setDocDueDate(orrr.getDocDueDate());
            List<SapOrderItem> list=new ArrayList<>();
            for (Object documentLine : orrr.getDocumentLines()) {
                SapOrderItem item = (SapOrderItem) documentLine;
                SapOrderItem newItem=new SapOrderItem();
                //修改绑定
                newItem.setBaseEntry(orrr.getDocEntry());
                newItem.setBaseType("234000031");
                newItem.setBaseLine(item.getLineNum());
                newItem.setQuantity(item.getQuantity());
                //设置收货批次
                newItem.setBatchNumbers(getReturnBatchNumber(deliveryOrder,orrr.getCardCode(),batchNumberService,item.getItemCode(),item.getWarehouseCode(),item.getQuantity()));
                list.add(newItem);
            }
            reqReturn.setDocumentLines(list);
            return JsonUtils.object2Json(reqReturn);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取一个物料的收货批次
     * @param deliveryOrder 如果有交货，就从交货里取发货批次
     * @param batchNumberService 如果没有交货或者交货信息里没有此物料的发货批次，则调用该方法获取库存批次
     * @param itemCode
     * @param whsCode
     * @return
     */
    private List<SapOrderItemBatch> getReturnBatchNumber(SapOrder deliveryOrder,String cardCode, IBatchNumberService batchNumberService, String itemCode, String whsCode, BigDecimal quantity){
        List<SapOrderItemBatch> list=null;
        SapOrderItemBatch batch=new SapOrderItemBatch();

        log.debug("生成{}的收货批次",itemCode);
        String batchNumber="";
        if(deliveryOrder!=null){
            log.debug("从发货批次里找");
            try {
                list = returnRequestDao.occupiedStock(deliveryOrder, itemCode, quantity);
            } catch (QuantityNotSufficientException e) {
                e.printStackTrace();
                list=new ArrayList<>();
                SapOrderItem o =(SapOrderItem) deliveryOrder.getDocumentLines().stream().filter(k -> ((SapOrderItem) k).getItemCode().equals(itemCode)).findFirst().orElse(null);
                if(o!=null){//发货有此物料
                    batch.setBatchNumber(o.getBatchNumbers().get(0).getBatchNumber());
                    batch.setQuantity(quantity);
                    list.add(batch);
                    return list;
                }
                //发货没有此物料，继续从库存批次里选
            }
            if(list!=null && list.size()>0){
                return list;
            }
            log.debug("发货批次里没有该物料");
        }
        log.debug("查询这个物料这个客户的最近发货批次");
        list=new ArrayList<>();
        String batchNumber1 = batchNumberService.getCardOutBatchNumber(cardCode,itemCode);

        if(StringUtils.hasText(batchNumber1)){
            batch.setBatchNumber(batchNumber1);
            log.debug("客户最近发货批次：{}",batch.getBatchNumber());
        }else{
            SapOrderItemBatch batch1 = batchNumberService.getItemBatchNumbers(itemCode, whsCode).stream().sorted(Comparator.comparing(SapOrderItemBatch::getBatchNumber).reversed()).findFirst().orElse(null);
            batch.setBatchNumber(batch1.getBatchNumber());
            log.debug("仓库物料批次：{}",batch.getBatchNumber());
        }
        batch.setQuantity(quantity);
        list.add(batch);
        return list;
    }
}
